package com.loklok.code.confuse.util;

import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PsiClassReferenceType;
import com.intellij.psi.search.GlobalSearchScope;

import java.util.ArrayList;
import java.util.List;

public class PsiFileUtils {


    /**
     * 根据包名和类名获取 PsiClass 对象
     *
     * @param project 项目对象
     * @param packageName 包名，例如: "com.example"
     * @param className 类名，例如: "MyClass"
     * @return PsiClass 对象
     */
    /**
     * @param packageName 包名，例如: "com.example"
     * @param className 类名，例如: "MyClass"
     * @return PsiClass 对象
     */
    public static PsiClass getPsiClassByPackageAndName(Project project, String packageName, String className) {
        try {
            // 使用 ApplicationManager.getApplication().runReadAction 包装需要读取访问权限的操作
            return ApplicationManager.getApplication().runReadAction((Computable<PsiClass>) () -> {
                // 使用 JavaPsiFacade 查找类
                JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
                String fullClassName = packageName + "." + className;
                return psiFacade.findClass(fullClassName, GlobalSearchScope.projectScope(project));
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }



    public static List<PsiClass> getSelectedClasses(AnActionEvent event) {
        Project project = event.getProject();
        VirtualFile[] selectedFiles = event.getData(CommonDataKeys.VIRTUAL_FILE_ARRAY);

        List<PsiClass> selectedClasses = new ArrayList<>();

        if (project == null || selectedFiles == null) {
            return selectedClasses;
        }

        for (VirtualFile file : selectedFiles) {
            if (file.isDirectory()) {
                // 如果是目录（包），递归处理包下的所有类
                processDirectory(project, file, selectedClasses);
            } else {
                // 否则处理单个文件
                PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
                if (psiFile instanceof PsiJavaFile) {
                    PsiClass[] classes = ((PsiJavaFile) psiFile).getClasses();
                    if (classes.length > 0) {
                        selectedClasses.add(classes[0]);
                    }
                }
            }
        }

        return selectedClasses;
    }

    /**
     * 递归处理目录下的所有 Java 文件，提取类
     */
    private static void processDirectory(Project project, VirtualFile directory, List<PsiClass> classList) {
        ApplicationManager.getApplication().runReadAction((Computable<Void>) () -> {
            for (VirtualFile child : directory.getChildren()) {
                if (child.isDirectory()) {
                    processDirectory(project, child, classList);
                } else {
                    PsiFile psiFile = PsiManager.getInstance(project).findFile(child);
                    if (psiFile instanceof PsiJavaFile) {
                        PsiClass[] classes = ((PsiJavaFile) psiFile).getClasses();
                        if (classes.length > 0) {
                            classList.add(classes[0]);
                        }
                    }
                }
            }
            return null;
        });
    }



    /**
     * 从字符串创建 PsiType 对象（如 "com.example.ResultResponse<com.example.User>"）
     */
    public static PsiType createTypeFromText(String typeText, Project project) {
        return JavaPsiFacade.getElementFactory(project).createTypeByFQClassName(typeText);
    }

    /**
     * 获取基础类型名称（去掉泛型部分）
     */
    public static String getBaseTypeName(PsiType psiType) {
        if (psiType instanceof PsiClassReferenceType) {
            return ((PsiClassReferenceType) psiType).getClassName();
        }
        return psiType.getPresentableText(); // fallback
    }


    public static List<String> extractGenericTypes(PsiType psiType, String packageNamePrefix) {
        List<String> result = new ArrayList<>();

        if (psiType instanceof PsiClassReferenceType) {
            PsiClassReferenceType referenceType = (PsiClassReferenceType) psiType;
            for (PsiType param : referenceType.getParameters()) {
                // 递归提取嵌套泛型
                List<String> nestedGenerics = extractGenericTypes(param, packageNamePrefix);

                if (nestedGenerics.isEmpty()) {
                    String canonicalText = param.getCanonicalText();
                    if (canonicalText.startsWith(packageNamePrefix)) {
                        result.add(canonicalText);
                    }
                } else {
                    result.addAll(nestedGenerics);
                }
            }
        }

        return result;
    }
    // 判断是否是 java.util.List / Set / Map 等集合类型
    private static boolean isCollectionType(PsiType psiType) {
        if (psiType instanceof PsiClassReferenceType) {
            PsiClassReferenceType referenceType = (PsiClassReferenceType) psiType;
            String className = referenceType.getClassName();
            return className.equals("List") || className.equals("Set") ||
                    className.equals("Map") || className.equals("Collection");
        }
        return false;

    }




    /**
     * 判断是否是 java.util.List 类型
     */
    public static boolean isListType(PsiType psiType) {
        return isOfType(psiType, "java.util.List");
    }

    /**
     * 判断是否是 java.util.Set 类型
     */
    public static boolean isSetType(PsiType psiType) {
        return isOfType(psiType, "java.util.Set");
    }

    /**
     * 判断是否是 java.util.Map 类型
     */
    public static boolean isMapType(PsiType psiType) {
        return isOfType(psiType, "java.util.Map");
    }

    /**
     * 判断是否是指定类型的引用
     */
    private static boolean isOfType(PsiType psiType, String className) {
        if (!(psiType instanceof PsiClassReferenceType)) {
            return false;
        }
        PsiClass psiClass = ((PsiClassReferenceType) psiType).resolve();
        return psiClass != null && className.equals(psiClass.getQualifiedName());
    }


    /**
     * 从字符串构建 PsiType 并获取基础类型名
     */
    public static String getBaseTypeName(String returnTypeText, Project project) {
        PsiType psiType = createTypeFromText(returnTypeText, project);
        return psiType != null ? getBaseTypeName(psiType) : "";
    }

    /**
     * 判断字符串表示的类型是否为指定类型（如 ResultResponse<T>）
     */
    public static boolean isWrappedType(String returnTypeText, String wrapperFqn, Project project) {
        PsiType psiType = createTypeFromText(returnTypeText, project);
        if (!(psiType instanceof PsiClassReferenceType)) {
            return false;
        }

        PsiClass psiClass = ((PsiClassReferenceType) psiType).resolve();
        return psiClass != null && wrapperFqn.equals(psiClass.getQualifiedName());
    }

    /**
     * 构造嵌套泛型信息（如 List<LiveRoomVo> -> [List, LiveRoomVo]）
     */
    public static GenericTypeResolver.ResolvedTypeInfo resolveNestedGenerics(String returnTypeText, Project project) {
        PsiType psiType = createTypeFromText(returnTypeText, project);
        if (psiType == null) {
            return new GenericTypeResolver.ResolvedTypeInfo("", List.of());
        }
        return GenericTypeResolver.resolveNestedGeneric(psiType);
    }
}
